/*
 * InputQueue.java    0.0.1    17/set/2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */ 
package org.mentalsmash.tazio.net.cs.server.impl;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

/**
 * The InputQueue is a wrapper for the ByteBuffer containing incoming data from a channel.
 * It provides convenience methods to access the buffer and hides unnecessary operations.
 * <p>
 * This class and all the classes in this package are largely inspired to the presentation
 * "How To Build A Scalable NIO Server, Mark II" by Ron Hitchens (http://ronsoft.com)
 * </p>
 * @version    0.0.1    17/set/2009    
 * @author     Andrea Reale <andrea.reale@gmail.com>
 */
public interface InputQueue {
	/**
	 * Reads from the channel source into the queue. The actual amount of data read depends
	 * on the implementation of the InputQueue. Therefore there's no guarantee that the whole data
	 * on the channel will be read in a single fill operation.
	 * @param source The channel to read from
	 * @return the actual number of bytes that were read from the channel. It might be 0 or -1 in case
	 *         of end-of-stream
	 * @throws IOException If some problem happens when accessing the channel.
	 */
	int fillFrom(ReadableByteChannel source) throws IOException;
	
	/**
	 * Checks whether the queue is empty
	 * @return true if the queue is empty
	 */
	boolean isEmpty();
	
	/**
	 * Returns the index inside the queue of the first occurrence of the byte passed as argument
	 * @param b the byte whom position is needed to know
	 * @return the index of the byte inside the queue or -1 if no occurrence of b is found
	 */
	int indexOf(byte b);
	
	/**
	 * Dequeues up to <code>count</code> bytes from the queue and returns them in a ByteBuffer.
	 * @param count the maximum number of bytes to dequeue.
	 * @return a ByteBuffered containing up to <code>count</code> dequeued bytes
	 */
	ByteBuffer dequeueBytes(int count);
	
	/**
	 * Returns the number of bytes currently in the queue
	 * @return the number of bytes currently in the queue
	 */
	int size();
	
	/**
	 * Tries to copy the first <code>count</code> bytes from the queue into a byte array,
	 * without dequeuing them from the queue. If there are fewer then <code>count</code>
	 * bytes in the queue returns <code>null</code>
	 * @param count the number of bytes to peek from the queue
	 * @return a copy of the first <code>count</code> bytes in the queue of <code>null</code>
	 *         if fewer then <code>count</code> bytes are currently in the queue
	 */
	byte[] peek(int count);
	
}
